<?php

namespace App\Http\Controllers\Api;

use App\Exceptions\BusinessException;
use App\Http\Controllers\Controller;
use App\Http\Resources\GoodsModelResource;
use App\Models\FavModel;
use App\Models\GoodsPicModel;
use App\Models\GoodsPicPrimaryModel;
use App\Models\GoodsPicPrimaryViewModel;
use App\Models\SupplyModel;
use App\Models\User;
use App\Models\UserModel;
use App\Models\VipGoodsModel;
use App\Utils\ControllerModelTrait;
use App\Utils\ResponseEnum;
use Carbon\Carbon;
use Hfm\BaiduAi\BaiduAI;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

class GoodsController extends ApiController
{
    use ControllerModelTrait;
    const CACHE_KEY = 'goodsImages-';

    /**
     * 获取商品（图片）列表
     * @param Request $request
     * @return JsonResponse
     */
    public function getList(Request $request): JsonResponse
    {
        $paginate = GoodsPicPrimaryViewModel::getModel($request)->orderByDesc('ID')
            ->select(['ID', 'SID', 'PName', 'FName', 'Path', 'PHotNum', 'ToySn', 'IsRight', 'IsNew', 'skuFlag', 'SName', 'ITime'])
            ->paginate(20);
        return $this->success($this->getPaginate($paginate, GoodsModelResource::collection($paginate->items())));
    }

    /**
     * 获取商家代发商品
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function getSkuGoodsList(Request $request): JsonResponse
    {
        $sid = $this->verifyId('sid');
        $Model = GoodsPicPrimaryModel::where('SID', $sid);
        $status = $request->input('status', 0);
        if ($status == 0)
            $Model = $Model->where('skuFlag', 1)->where('PStatus', 0);
        else {
            if ($status == -1)
                $Model = $Model->where('skuFlag', 0)->where('PStatus', 0);
            else
                $Model = $Model->where('PStatus', $status);
        }
        if ($request->input('keyword')) {
            $keyword = $request->input('keyword');
            if (is_numeric($keyword))
                $Model = $Model->whereRaw('instr(ToySn, "'. $keyword .'") > 0');
            else
                $Model = $Model->whereRaw('instr(PName, "'.$keyword.'") > 0');
        }
        $paginate = $Model->select(['ID', 'SID', 'PName', 'FName', 'Path', 'PHotNum', 'ToySn', 'skuFlag', 'SName', 'ITime', 'PStatus'])->paginate(20);
        return $this->success($this->getPaginate($paginate, GoodsModelResource::collection($paginate->items())));
    }

    /**
     * 上架/下架商品
     * @return JsonResponse
     * @throws BusinessException
     */
    public function setGoodsStatus(): JsonResponse
    {
        $goodsId = $this->verifyId('goods_id');
        $status = $this->verifyNumeric('status');
        GoodsPicPrimaryModel::where('ID', $goodsId)->update(['PStatus' => $status]);
        GoodsPicModel::where('ID', $goodsId)->where('PID', 0)->update(['PStatus' => $status]);
        return $this->success();
    }

    /**
     * 获取推荐视频列表(网页)
     * @param Request $request
     * @return JsonResponse
     */
    public function videoList(Request $request): JsonResponse
    {
        if (!Cache::has('videos')) {
            $videos = GoodsPicModel::where('IsVideo', 1)->distinct('PID')->select(['PID', 'ID', 'Path', 'FName', 'IsVideo', 'IsEncry'])
                ->orderByDesc('ITime')->limit(6)->get();
            $dictionary = [];
            if ($videos) {
                foreach ($videos as $v)
                    $dictionary[$v->PID] = Controller::getImageFullUrl($v);
                $goods = GoodsPicPrimaryModel::whereIn('ID', array_keys($dictionary))->select(['ID', 'PName', 'SID', 'SName', 'Path', 'FName', 'IsEncry'])->get();
                $supplies = SupplyModel::whereIn('ID', $goods->pluck('SID')->toArray())->pluck('Addr', 'ID')->toArray();
                foreach ($goods as &$v) {
                    $v->Addr = $supplies[$v->SID];
                    $v->cover = Controller::getImageFullUrl($v);
                    $v->video = $dictionary[$v->ID];
                }
                Cache::put('videos', $goods, 5 * 60);
            }
        }
        return $this->success(Cache::get('videos'));
    }

    /**
     * 关键词搜索
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function keywordSearch(Request $request): JsonResponse
    {
        $area_id = $this->verifyString('area_id');
        $Model = GoodsPicPrimaryViewModel::where('PID', 0)->where('PStatus', 0)
            ->whereIn('AreaID', GoodsPicPrimaryViewModel::getAreaMapRelation($area_id));
        $keyword = $request->input('keyword', '');
        if ($keyword)
            $Model = is_numeric($keyword) ? $Model->whereRaw('instr(ToySn, "'. $keyword .'") > 0')
                : $Model->whereRaw('(instr(PName, "'.$keyword.'") > 0 OR instr(SName, "'.$keyword.'"))');
        $paginate = $Model->orderByDesc('ID')->paginate(20);
        return $this->success($this->getPaginate($paginate, GoodsModelResource::collection($paginate->items())));
    }

    /**
     * 以图搜图 # 修改BaiduAI文件
     * @param Request $request
     * @return JsonResponse
     */
    public function imageSearch(Request $request): JsonResponse
    {
        $file = $request->file('image');
        $AI = new BaiduAI('44946779', 'jk7cCd7yVH1R7G02DCslsiqr', 'hywd2k5WI83RpKdXlp1Pl4UzIVn2gn2r');
        $response = $AI->searchImage('', file_get_contents($file->getRealPath()));
        if (!$response)
            $data = [];
        else
            $data = GoodsModelResource::collection(GoodsPicPrimaryModel::where('PStatus', 0)
                ->whereIn('ID', $this->getPidFromAIResponse($response))->orderByDesc('ID')->get());
        $total = count($data);
        return $this->success([
            'total' => $total,
            'page'  => 1,
            'page_size' => $total,
            'pages' => 1,
            'list'  => $data,
        ]);
    }


    /**
     * 图片下载
     * @throws BusinessException
     */
    public function getDownloadList(): JsonResponse
    {
        $id = $this->verifyNumeric('pid');
        $imagesCollection = GoodsPicModel::where('ID', $id)->orWhere('PID', $id)->select(['PID', 'FName', 'Path', 'IsVideo'])->get();
        if (empty($imagesCollection))
            return $this->fail(ResponseEnum::CLIENT_DELETED_ERROR);
        $cover = $this->getImageAndThumb($imagesCollection->where('PID', 0), '');
        $data = [
            ['label' => '主图', 'list' => $cover],
            ['label' => '视频', 'list' => $this->getImageAndThumb($imagesCollection->where('IsVideo', 1), $cover[0]['thumbnail'])],
            ['label' => '详情图', 'list' => $this->getImageAndThumb($imagesCollection->where('IsVideo', 0)->where('PID', $id), '')],
        ];
        return $this->success($data);
    }

    /**
     * 查看商品计算点击量
     * @return JsonResponse
     * @throws BusinessException
     */
    public function viewGoods(): JsonResponse
    {
        $id = $this->verifyInteger('id');
        $count = GoodsPicModel::where('PID', $id)->orWhere('ID', $id)->count('ID');
        #todo 电脑端修改
        GoodsPicPrimaryModel::where('ID', $id)->increment('PHotNum', $count);
        return $this->success();
    }

    /**
     * 获取商品（图片）详情
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function goodsInfo(Request $request): JsonResponse
    {
        $id = $this->verifyInteger('id');
        $goods = GoodsPicPrimaryModel::where('ID', $id)
            ->select(['ID', 'PID', 'SID', 'SName', 'Path', 'PName', 'FName', 'IsEncry', 'IsPaid', 'ToySn', 'PHotNum', 'HotNum', 'ITime', 'CTime', 'skuFlag', 'ali_url'])
            ->first();
        if (!$goods)
            return $this->fail(ResponseEnum::CLIENT_DELETED_ERROR);
        $collection = self::getGoodsImagesCollection($id);
        $goods->pics = $this->getTopImagesAndVideo($collection, $goods);
        $goods->imageList = $this->getPicAllList($collection);
        $goods->supply = SupplyController::getSupplyCache($goods->SID);
        $goods->html = 'https://www.toysmodel.cn/rbhdist/#/?id='.$id;
        $goods->moreInfo = $this->getGoodsMoreInfo($id, $goods->IsPaid);
        if ($request->input('uuid'))
            $goods->is_fav = FavModel::where('uuid', $request->input('uuid'))->where('PID', $id)->first() ? 1 : 0;
        # 规格
        if ($request->input('sku'))
            $goods = $this->injectSpecIntoGoodsInfo($goods);
        return $this->success($goods);
    }

    /**
     * 下架商品
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function resetSkuFlag(Request $request): JsonResponse
    {
        $id = $this->verifyId('id');
        GoodsPicPrimaryModel::where('ID', $id)->update(['skuFlag' => 0, 'updated_at' => Carbon::now()->toDateTimeString()]);
        return $this->success();
    }

    /**
     * 获取图片列表缓存
     * @param $goods_id
     * @return mixed
     */
    public static function getGoodsImagesCollection($goods_id): mixed
    {
        return GoodsPicModel::where('ID', $goods_id)->orWhere('PID', $goods_id)
            ->select(['ID', 'PID', 'Path', 'FName', 'IsEncry', 'IsVideo'])
            ->get();
    }

    /**
     * 图片倒叙排序
     * @param $collection
     * @return mixed
     */
    private function getPicAllList($collection): mixed
    {
        $imagesList = $collection->where('PID', '>', 0)->where('IsVideo', 0)->toArray();
        if ($imagesList) {
            $ids = array_column($imagesList, 'ID');
            array_multisort($ids, SORT_DESC, $imagesList);
        }
        return $imagesList;
    }

    /**
     * 商品详情注入规格信息
     * @param $goods
     * @return mixed
     */
    private function injectSpecIntoGoodsInfo($goods): mixed
    {
        $specCollection = SpecController::getSpecCache($goods->ID);
        $specList = $specCollection->toArray();
        $specPriceList = array_column($specList, 'price');
        $specWeightList = array_column($specList, 'weight');
        sort($specPriceList);
        sort($specWeightList);
        $goods->price = isset($specPriceList[0]) ? $specPriceList[0] . '元起' : '';
        $goods->min_weight = $specWeightList[0] ?? 0;
        $goods->stock = '>1';
        $goods->specs = $this->getGroupSpecData($specCollection);
        return $goods;
    }

    /**
     * 规格归并分组
     * @param $collection
     * @return array
     */
    private function getGroupSpecData($collection): array
    {
        $specs = [];
        foreach ($collection as $item) {
//            $item->thumbnail = str_replace('http://www.toysmodel.cn', 'https://picture.toysmodel.cn:11443', $item->thumbnail);
            if (!isset($specs[$item->color]))
                $specs[$item->color] = ['color' => $item->color, 'list' => [$item]];
            else
                $specs[$item->color]['list'][] = $item;
        }
        return $collection ? array_values($specs) : [];
    }

    /**
     * 获取缩略图和大图数组
     * @param $itemData
     * @param string $thumbnail
     * @return array
     */
    private function getImageAndThumb($itemData, string $thumbnail): array
    {
        $data = [];
        foreach ($itemData as $item) {
            $data[] = [
                'thumbnail' => $thumbnail ?: Controller::getImageFullUrl($item, true),
                'file'      => Controller::getImageFullUrl($item),
            ];
        }
        return $data;
    }

    /**
     * 获取置顶图
     * @param $collection
     * @param $cover
     * @return array
     */
    private function getTopImagesAndVideo($collection, $cover): array
    {
        $topImageCollection = $collection->filter(function ($item) {
            return $item->PID == 0 || ($item->width > 0 && $item->width == $item->height);
        });
        $list = [];
        foreach ($topImageCollection as $pic) {
            $list[] = [
                'type'  => 1,
                'file'  => Controller::getImageFullUrl($pic),
                'width' => $pic->IsEncry > 0 ? 800 : 280,
                'height'=> $pic->IsEncry > 0 ? 800 : 280
            ];
        }
        // 合并视频
        $video = $this->getVideoList($collection, Controller::getImageFullUrl($cover));
        if ($video)
            $list = array_merge([$video], $list);
        return $list;
    }

    /**
     * 获取视频列表
     * @param $collection
     * @param string $poster
     * @return array|false
     */
    private function getVideoList($collection, string $poster): bool|array
    {
        $video = $collection->where('IsVideo', 1)->first();
        if (!$video)
            return false;
        else {
            return  [
                'type' => 2,
                'poster' => $poster,
                'file' => Controller::getImageFullUrl($video),
            ];
        }
    }

    /**
     * 提前相似图片ID
     * @param array $response
     * @return array
     */
    private function getPidFromAIResponse(array $response): array
    {
        $ids = [];
        foreach ($response as $item) {
            if ($item['score'] < 0.6)
                continue;
            $brief = json_decode($item['brief'], true);
            if (isset($brief['pid']) && $brief['pid'])
                $ids[] = $brief['pid'];
        }
        return array_unique(array_values($ids));
    }

    /**
     * 获取商品扩展信息
     * @param $goods_id
     * @param $vip
     * @return mixed
     */
    private function getGoodsMoreInfo($goods_id, $vip): mixed
    {
        $default = [
            'OPrice'    => '仅VIP可见，需商家授权',
            'Weight'    => '仅VIP可见，需商家授权',
            'ToySize'   => '仅VIP可见，需商家授权'
        ];
        if ($vip) {
			$sid = GoodsPicPrimaryModel::where('ID', $goods_id)->value('SID');
            if (!request()->input('uid'))
                return $default;
            if (!VipGoodsModel::where('sid', $sid)->where('uuid', request()->input('uid'))->first())
                return $default;
        }
        $key = 'goodsMore-'. $goods_id;
        if (!Cache::has($key))
            Cache::put($key, DB::connection('rbh')->table('pic_gg')->where('PID', $goods_id)->first(), 3 * 60);
        return Cache::get($key);
    }
}
